var CheckboxTableColumn = function () {
  var template = /*html*/ `
    <el-table-column :resizable="resizable" :width="width" :min-width="minWidth" :fixed="fixed" :key="key" :column-key="columnKey" :align="align" :header-align="headerAlign">
      <template slot="header" slot-scope="props">
        <el-checkbox v-model="isCheckAll" :indeterminate="indeterminate" :disabled="disabled" @change="checkAll" :label="headerText" @click.native.stop>
        </el-checkbox>
      </template>
      <template slot-scope="props">
        <el-checkbox :disabled="getRowCanSelect(props.row)" :checked="getChecked(props.row)" @click.native.stop 
          @change="function(checked){checkRow(props.row,checked)}">
        </el-checkbox>
      </template>
    </el-table-column>
  `;

  return {
    props: {
      width: {
        type: String,
        default: undefined
      },
      minWidth: {
        type: String,
        default: undefined
      },
      headerText: String,
      resizable: {
        type: Boolean,
        default: false
      },
      fixed: {
        validator: function (value) {
          return [true, false, 'left', 'right'].indexOf(value) !== -1;
        },
        default: false
      },
      selectable: {
        type: [Function, Boolean],
        default: true
      },
      checkField: {
        type: String,
        default: 'id'
      },
      columnKey: String,
      key: String,
      align: String,
      headerAlign: String,
      checkSelect:Function
    },
    computed: {
      data: function () {
        return this.$parent.data;
      },

      disabled: function () {
        var data = this.data;
        data = this.getCheckedData(data);
        return data.length === 0;
      }
    },
    watch: {
      data: function () {
        this.selectIds = [];
        this.isCheckAll = false;
        this.indeterminate = false;
      }
    },
    data: function () {
      return {
        isCheckAll: false,
        indeterminate: false,
        selectIds: []
      };
    },
    methods: {
      getChecked: function (row) {
        var selectIds = this.selectIds;
        var checkField = this.checkField;
        return selectIds.indexOf(row[checkField]) !== -1;
      },

      checkRow: function (row, checked) {
        var flag = true;
        var checkSelect = this.checkSelect;
        if (checkSelect !== undefined) {
          flag = checkSelect();
        }

        var selectIds = this.selectIds;
        if (!flag) {
          var self = this;
          var rowIds = _.cloneDeep(selectIds);
          this.$nextTick(function(){
            self.selectIds = rowIds;
          });
        }

        var checkField = this.checkField;
        var id = row[checkField];
        var index = selectIds.indexOf(id);
        if (checked) {
          if (index === -1) {
            selectIds.push(id);
          }
        } else {
          if (index !== -1) {
            selectIds.splice(index, 1);
          }
        }
        if (!flag) {
          return;
        }

        this.resetCheckAll();
        var data = this.data;
        var selectData = _.filter(data, function (obj) {
          return selectIds.indexOf(obj[checkField]) !== -1;
        });
        this.$emit('select-change', selectIds, selectData);
      },

      checkAll: function () {
        var flag = true;
        var checkSelect = this.checkSelect;
        if (checkSelect !== undefined) {
          flag = checkSelect();
        }

        var checked = this.isCheckAll;
        if (checked) {
          if (flag) {
            this.selectAll();
          }
        } else {
          if (flag) {
            this.selectIds = [];
          }
        }

        if (!flag) {
          var self = this;
          this.$nextTick(function(){
            self.isCheckAll = !checked;
          });
          return;
        }

        this.indeterminate = false;
        var data = this.data;
        var checkField = this.checkField;
        var selectIds = this.selectIds;
        var selectData = _.filter(data, function (obj) {
          return selectIds.indexOf(obj[checkField]) !== -1;
        });
        this.$emit('select-change', selectIds, selectData);
      },

      selectAll: function () {
        var data = this.data;
        data = this.getCheckedData(data);
        this.selectIds = _.map(data, this.checkField);
      },

      toggleRowSelection: function (ids, checked) {
        var data = this.data;
        var checkField = this.checkField;
        var selectIds = [];
        for (var i = 0; i < data.length; i++) {
          var d = data[i];
          var id = d[checkField];
          if (ids.indexOf(id) !== -1) {
            selectIds.push(id);
          }
        }
        if (checked) {
          this.selectIds = _.union(this.selectIds, selectIds);
        } else {
          this.selectIds = _.difference(this.selectIds, selectIds);
        }

        this.resetCheckAll();
      },

      clearSelect: function () {
        this.selectIds = [];
        this.resetCheckAll();
      },

      resetCheckAll: function () {
        var selectIds = this.selectIds;
        var data = this.data;
        data = this.getCheckedData(data);

        if (data.length === 0) {
          this.isCheckAll = false;
          this.indeterminate = false;
          return;
        }

        if (selectIds.length === data.length) {
          this.isCheckAll = true;
          this.indeterminate = false;
        } else if (selectIds.length === 0) {
          this.isCheckAll = false;
          this.indeterminate = false;
        } else {
          this.isCheckAll = false;
          this.indeterminate = true;
        }
      },

      getCheckedData: function (data) {
        var selectable = this.selectable;
        if (selectable !== undefined) {
          data = _.filter(data, function (d) {
            if (typeof selectable === 'boolean') {
              return selectable;
            }
            return selectable(d);
          });
        }
        return data;
      },

      getRowCanSelect: function (row) {
        var selectable = this.selectable;
        if (selectable === undefined) {
          return false;
        }
        if (typeof selectable === 'boolean') {
          return !selectable;
        }
        return !selectable(row);
      }
    },
    template: template
  };
}();
